package zhoug.player.qly;

import android.app.Application;
import android.content.Context;
import android.text.TextUtils;

import com.cmcc.qlyopensdk.init.IGlobalCache;
import com.cmcc.qlyopensdk.init.config.header.HeaderManager;
import com.cmcc.qlyopensdk.init.impl.GlobalCache;
import com.cmcc.qlyopensdk.init.impl.QlyOpenSdk;
import com.cmcc.qlyopensdk.net.HttpManager;
import com.cmcc.qlyopensdk.net.bean.BaseResponse;
import com.cmcc.qlyopensdk.net.callback.NetCallBack;
import com.cmcc.qlyopensdk.net.impl.HttpRequest;
import com.cmcc.qlyopensdk.net.restapi.IQlyOpenSdkApi;
import com.cmcc.qlyopensdk.net.restapi.impl.QlyOpenSdkApi;
import com.cmcc.qlyopensdk.player.constant.PlayerHD;
import com.cmcc.qlyopensdk.player.constant.ServerEnv;
import com.cmcc.qlyopensdk.utils.DeviceUtils;
import com.cmcc.qlyopensdk.utils.MD5Utils;
import com.cmcc.qlyopensdk.utils.TypeUtils;
import com.cmcc.qlyopensdk.vo.response.CameraSettingInfo;
import com.cmcc.qlyopensdk.vo.response.QlyPlatformToken;
import com.cmcc.qlyopensdk.vo.response.TimeLineSectionBean;
import com.cmcc.vnsdk.camera.restapi.model.response.OpenPlatformToken;
import com.google.gson.JsonObject;

import zhoug.common.utils.ThreadUtils;
import zhoug.logging.Logger;
import zhoug.player.core.Callback;
import zhoug.player.core.CameraAbility;
import zhoug.player.core.CameraInfo;
import zhoug.player.core.CameraToken;
import zhoug.player.core.OnCameraAbilityCallback;
import zhoug.player.core.OnCameraSettingCallback;
import zhoug.player.core.PlayError;
import zhoug.player.core.PlayerSDK2;
import zhoug.player.core.RecordSegment;
import zhoug.player.core.ZPlayer;

import java.util.List;

import androidx.annotation.NonNull;
import kotlin.jvm.internal.Intrinsics;

/**
 * 千里眼sdk 配置和接口
 *
 * @Author: zhoug
 * @Date: 2024-12-09
 * @Description:
 */
public class QlySdk {
    private static final String TAG = ">>>QlySdk";
    private static final boolean DEBUG = PlayerSDK2.isDebug();
    /**
     * 获取token类型
     * 1：应用token(拥有该应用全部权限)，2：自定义token(拥有该应用部分权限)
     */
    public static final int TOKEN_OPERATOR_TYPE_APP = 1;
    public static final int TOKEN_OPERATOR_TYPE_CUSTOM = 2;
    /**
     * 资源类型
     * 2：设备，获取应用token时不传
     */
    public static final String TARGET_TYPE_DEVICE = "2";

    /**
     * 行为
     * read：只读，write：可读可写
     */
    public static final String ACTION_WRITE = "write";
    public static final String ACTION_READ = "read";

    /**
     * 千里眼api baseUrl
     */
    private static final String API_BASE_HOST = "https://hoa.and-home.cn/";
    /**
     * 获取token的接口
     */
    private static final String API_GET_TOKEN = "v3/open/api/token";
    /**
     * 获取设备列表的接口
     */
    private static final String API_GET_DEVICE_LIST = "v3/open/api/device/list";


    /**
     * 初始化播放器
     * 在使用播放器之前必须先调用此方法初始化
     *
     * @param application
     * @param debug
     */
    public static void init(Application application, String appId, String privateKey, boolean debug) {
        if (DEBUG)
            Logger.d(TAG, "init:初始化 QlyOpenSdk");
        //设置为发布环境
        QlyOpenSdk.getInstance().setServerEnv(ServerEnv.SERVER_ENV_PRO);
        //打印日志
        QlyOpenSdk.getInstance().setDebug(debug);
        QlyOpenSdk.getInstance().init(application, appId, privateKey);
        /*QlyOpenSdk.getInstance().setLogCallback(new LogCallback() {
            @Override
            public void onPrintLog(String value1, String value2) {
                Logger.d(TAG, "onPrintLog:value1="+value1+",value2="+value2);
            }
        });*/
    }

    /**
     * 设置平台级别token
     *
     * @param token
     * @deprecated use {@link #setOpenPlatformToken1}
     */
    @Deprecated
    public static void setOpenPlatformToken(String token) {
        if (DEBUG)
            Logger.d(TAG, "设置token:" + token);
        QlyOpenSdk.getInstance().setOpenPlatformToken(token);
    }

    /**
     * 设置平台级别token
     * 根据千里眼api源码重写,新增回掉接口
     *
     * @param token
     * @param callback
     */
    public static void setOpenPlatformToken1(String token, Callback<Boolean> callback) {
        if (DEBUG)
            Logger.d(TAG, "设置token:" + token);
        QlyOpenSdk.getInstance().setOpenPlatformToken(token);
        Intrinsics.checkNotNullParameter(token, "token");
        GlobalCache.getInstance().setConfig("open_platform_token", token);
        IQlyOpenSdkApi api = QlyOpenSdkApi.Companion.getInstance();
        api.getQlyPlatformToken("eab463a0ab013715704d805ddfa03471", token, new NetCallBack<BaseResponse<QlyPlatformToken>>() {
            @Override
            public void onResponse(BaseResponse<QlyPlatformToken> response) {
                if (response == null) {
                    if (callback != null) {
                        callback.onError(PlayError.TOKEN_EXPIRE, "response is null");
                    }
                    return;
                }
                if (response.isSuccess() && response.getData() != null) {
                    QlyPlatformToken qlyPlatformToken = response.getData();
                    if (!TextUtils.isEmpty(qlyPlatformToken.getToken()) && !TextUtils.isEmpty(qlyPlatformToken.getRegion())) {
                        IGlobalCache api = GlobalCache.getInstance();
                        String token = qlyPlatformToken.getToken();
                        api.setConfig("qly_platform_token", token);
                        api = GlobalCache.getInstance();
                        String region = qlyPlatformToken.getRegion();
                        api.setConfig("qly_platform_region", region);
                        if (callback != null) {
                            callback.onSuccess(true);
                        }
                    } else {
                        if (callback != null) {
                            callback.onError(PlayError.TOKEN_EXPIRE, "无效的千里眼Token");
                        }
                    }
                } else {
                    if (callback != null) {
                        callback.onError(PlayError.TOKEN_EXPIRE, response.getResultMsg());
                    }
                }
            }

            @Override
            public void onError(Throwable throwable) {
                if (callback != null) {
                    callback.onError(PlayError.TOKEN_EXPIRE, throwable != null ? throwable.getMessage() : "设置token失败");
                }
            }
        });


    }

    /**
     * 获取设备id
     *
     * @param deviceId
     * @return
     */
    public static String getMacByDeviceId(String deviceId) {
        return DeviceUtils.getMacByDeviceId(deviceId);
    }

    /**
     * 根据appId和secret生成接口签名
     *
     * @param appId
     * @param secret
     * @return
     */
    public static String sig(String appId, String secret) {
        return MD5Utils.md5(appId + secret);
    }

    /**
     * 根据接口path获取完整的接口路径
     *
     * @param path
     * @return
     */
    public static String getApiUrl(@NonNull String path) {
        return API_BASE_HOST + path;
    }

    /**
     * 获取token
     *
     * @param tokenInfo
     */
    public static void getOpenPlatformToken(QlyTokenParams tokenInfo, @NonNull Callback<CameraToken> callBack) {
        String sig = sig(tokenInfo.getAppId(), tokenInfo.getSecret());
        JsonObject params = new JsonObject();
        params.addProperty("operatorType", tokenInfo.getOperatorType());
        params.addProperty("action", tokenInfo.getAction());
        params.addProperty("targetType", tokenInfo.getTargetType());
        params.addProperty("target", tokenInfo.getTarget());
        params.addProperty("sig", sig);
        String body = params.toString();
        HttpRequest request = new HttpRequest();
        request.body = body;
        request.url = getApiUrl(API_GET_TOKEN);
        request.headers = HeaderManager.getInstance().createHeader(body);
        HttpManager.getInstance().httpsPost(request, new NetCallBack<BaseResponse<OpenPlatformToken>>() {
                    @Override
                    public void onResponse(BaseResponse<OpenPlatformToken> response) {
                        ThreadUtils.runMainThread(() -> {
                            if (response.isSuccess()) {
                                CameraToken qlyToken = null;
                                OpenPlatformToken data = response.getData();
                                if (data != null) {
                                    String token = data.getToken();
                                    if (!TextUtils.isEmpty(token)) {
                                        qlyToken = new CameraToken();
                                        qlyToken.setToken(token);
                                        qlyToken.setExpiresIn(data.getExpires_in());
                                    }
                                }
                                if (qlyToken != null) {
                                    callBack.onSuccess(qlyToken);
                                } else {
                                    callBack.onError(PlayError.UNKNOWN_ERROR, "没有返回token");
                                }
                            } else {
                                callBack.onError(PlayError.UNKNOWN_ERROR, response.getResultMsg());
                            }
                        });
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        ThreadUtils.runMainThread(() -> {
                            callBack.onError(PlayError.UNKNOWN_ERROR, throwable.getMessage());

                        });
                    }
                },
                TypeUtils.createType(BaseResponse.class, OpenPlatformToken.class));
    }

    /**
     * 获取设备列表
     *
     * @param page
     * @param pageSize
     * @param callBack
     */
    public static void getDeviceList(int page, int pageSize, @NonNull Callback<List<CameraInfo>> callBack) {
        JsonObject params = new JsonObject();
        params.addProperty("page", page);
        params.addProperty("pageSize", pageSize);
        String body = params.toString();
        HttpRequest request = new HttpRequest();
        request.url = getApiUrl(API_GET_DEVICE_LIST);
        request.body = body;
        request.headers = HeaderManager.getInstance().createHeader(body);
        HttpManager.getInstance().httpsPost(request, new NetCallBack<BaseResponse<List<CameraInfo>>>() {
            @Override
            public void onResponse(BaseResponse<List<CameraInfo>> response) {
                if (response.isSuccess()) {
                    List<CameraInfo> data = response.getData();
                    callBack.onSuccess(data);
                } else {
                    callBack.onError(PlayError.UNKNOWN_ERROR, response.getResultMsg());
                }
            }

            @Override
            public void onError(Throwable throwable) {
                callBack.onError(PlayError.UNKNOWN_ERROR, throwable.getMessage());
            }
        }, TypeUtils.createListType(BaseResponse.class, CameraInfo.class));
    }

    /**
     * 连接设备
     *
     * @param context
     * @param deviceId 设备id {@link #getMacByDeviceId(String)}
     */
    public static void connectCamera(Context context, String deviceId, @NonNull Callback<String> callback) {
        QlyOpenSdk.getInstance().connect(context, deviceId, new NetCallBack<BaseResponse<String>>() {
            @Override
            public void onResponse(BaseResponse<String> response) {
                if (response.isSuccess()) {
                    ThreadUtils.runMainThread(() -> {
                        String data = response.getData();
                        if (!TextUtils.isEmpty(data)) {
                            callback.onSuccess(data);
                        } else {
                            callback.onError(PlayError.CONNECT_CAMERA_ERROR, "deviceId isEmpty");
                        }
                    });
                } else {
                    ThreadUtils.runMainThread(() -> {
                        callback.onError(PlayError.CONNECT_CAMERA_ERROR, response.getResultMsg());
                    });
                }
            }

            @Override
            public void onError(Throwable throwable) {
                ThreadUtils.runMainThread(() -> {
                    callback.onError(PlayError.CONNECT_CAMERA_ERROR, throwable.getMessage());

                });
            }
        });
    }

    /**
     * 断开设备连接
     */
    public static void disconnect() {
        QlyOpenSdk.getInstance().disconnect();
    }

    /**
     * 获取设备能力
     *
     * @param deviceId {@link #getMacByDeviceId(String)}
     */
    public static void getCameraAbility(String deviceId, OnCameraAbilityCallback callback) {
        QlyOpenSdk.getInstance().getDeviceAbility(deviceId, new NetCallBack<BaseResponse<com.cmcc.qlyopensdk.vo.response.CameraAbility>>() {
            @Override
            public void onResponse(BaseResponse<com.cmcc.qlyopensdk.vo.response.CameraAbility> response) {
                if (response.isSuccess()) {
                    com.cmcc.qlyopensdk.vo.response.CameraAbility data = response.getData();
                    if (data != null) {
                        CameraAbility cameraAbility = QlyDataParser.parse(data);
                        if (callback != null) {
                            ThreadUtils.runMainThread(() -> callback.onCameraAbilitySuccess(cameraAbility));
                        }

                    } else {
                        if (callback != null) {
                            ThreadUtils.runMainThread(() -> callback.onCameraAbilityError("CameraAbility is null"));
                        }

                    }
                } else {
                    if (callback != null) {
                        ThreadUtils.runMainThread(() -> callback.onCameraAbilityError(response.getResultMsg()));
                    }

                }
            }

            @Override
            public void onError(Throwable throwable) {
                if (callback != null) {
                    ThreadUtils.runMainThread(() -> callback.onCameraAbilityError(throwable.getMessage()));
                }

            }
        });
    }

    /**
     * 高标清切换
     *
     * @param deviceId 设备id {@link #getMacByDeviceId(String)}
     * @param hd       {@link ZPlayer#QUALITY_HD,ZPlayer#QUALITY_SD}
     * @param callback
     */
    public static void switchPlaybackQuality(String deviceId, int hd, @NonNull Callback<Integer> callback) {
        int quality = hd == ZPlayer.QUALITY_HD ? PlayerHD.ON : PlayerHD.OFF;
        QlyOpenSdk.getInstance().switchPlaybackQuality(deviceId, quality, new NetCallBack<BaseResponse<?>>() {
            @Override
            public void onResponse(BaseResponse<?> response) {
                if (response.isSuccess()) {
                    ThreadUtils.runMainThread(() -> {
                        callback.onSuccess(hd);
                    });
                } else {
                    ThreadUtils.runMainThread(() -> {
                        callback.onError(PlayError.UNKNOWN_ERROR, response.getResultMsg());
                    });
                }
            }

            @Override
            public void onError(Throwable throwable) {
                ThreadUtils.runMainThread(() -> {
                    callback.onError(PlayError.UNKNOWN_ERROR, throwable.getMessage());

                });
            }
        });
    }

    /**
     * 获取摄像头设置信息
     *
     * @param deviceId 设备id {@link #getMacByDeviceId(String)}
     * @param callback
     */
    public static void getCameraSettings(String deviceId, OnCameraSettingCallback callback) {
        QlyOpenSdk.getInstance().getSettings(deviceId, new NetCallBack<BaseResponse<List<CameraSettingInfo>>>() {
            @Override
            public void onResponse(BaseResponse<List<CameraSettingInfo>> response) {
                if (response.isSuccess()) {
                    List<CameraSettingInfo> data = response.getData();
                    if (data != null && !data.isEmpty()) {
                        if (callback != null) {
                            ThreadUtils.runMainThread(() -> callback.onCameraSettingSuccess(QlyDataParser.parse(data.get(0))));
                        }

                    } else {
                        if (callback != null) {
                            ThreadUtils.runMainThread(() -> callback.onCameraSettingError("没有获取到设置信息"));
                        }

                    }
                } else {
                    if (callback != null) {
                        ThreadUtils.runMainThread(response::getResultMsg);
                    }
                }
            }

            @Override
            public void onError(Throwable throwable) {
                if (callback != null) {
                    callback.onCameraSettingError(throwable.getMessage());
                }

            }
        });
    }

    /**
     * 获取云存储回放数据列表
     *
     * @param deviceId  设备id {@link #getMacByDeviceId(String)}
     * @param startTime 开始时间 毫秒
     * @param endTime   结束时间 毫秒
     * @param callback
     */
    public static void getTimelineSectionList(String deviceId, long startTime, long endTime, @NonNull Callback<List<RecordSegment>> callback) {
        QlyOpenSdk.getInstance().getTimelineSectionList(deviceId, startTime, endTime, new NetCallBack<BaseResponse<List<TimeLineSectionBean>>>() {
            @Override
            public void onResponse(BaseResponse<List<TimeLineSectionBean>> response) {
                if (response.isSuccess()) {
                    List<RecordSegment> segments = QlyDataParser.parseTimelineSectionResponse(response.getData());
                    ThreadUtils.runMainThread(() -> callback.onSuccess(segments));
                } else {
                    ThreadUtils.runMainThread(() -> callback.onError(PlayError.UNKNOWN_ERROR, response.getResultMsg()));
                }
            }

            @Override
            public void onError(Throwable throwable) {
                ThreadUtils.runMainThread(() -> callback.onError(PlayError.UNKNOWN_ERROR, throwable.getMessage()));
            }
        });
    }

    /**
     * 获取SD卡回放数据列表
     *
     * @param deviceId  设备id {@link #getMacByDeviceId(String)}
     * @param startTime 开始时间 毫秒
     * @param endTime   结束时间 毫秒
     * @param callback
     */
    public static void getSdcardTimelineSectionList(String deviceId, long startTime, long endTime, @NonNull Callback<List<RecordSegment>> callback) {
        QlyOpenSdk.getInstance().getTimelineSectionList(deviceId, startTime, endTime, new NetCallBack<BaseResponse<List<TimeLineSectionBean>>>() {
            @Override
            public void onResponse(BaseResponse<List<TimeLineSectionBean>> response) {
                if (response.isSuccess()) {
                    List<RecordSegment> segments = QlyDataParser.parseTimelineSectionResponse(response.getData());
                    ThreadUtils.runMainThread(() -> {
                        callback.onSuccess(segments);
                    });
                } else {

                    ThreadUtils.runMainThread(() -> {
                        callback.onError(PlayError.UNKNOWN_ERROR, response.getResultMsg());
                    });
                }

            }

            @Override
            public void onError(Throwable throwable) {
                ThreadUtils.runMainThread(() -> {
                    callback.onError(PlayError.UNKNOWN_ERROR, throwable.getMessage());
                });
            }
        });
    }


}
